package DataSetPackage;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;

public class ArffReader extends DataSetReader{
	
	@Override
	public DataSet readFile(String fileName) throws Exception {
		DataSet dataset = new DataSet();

		BufferedReader br = new BufferedReader(new FileReader(fileName));
		String line = br.readLine();
		while (line != null) {
			String[] strs = getLineArffLabel(line);
			if (strs.length > 1 && strs[0].equalsIgnoreCase("@attribute")) {
				Attribute att = readArffAttribute(strs[1].trim());
				if(att == null)
				{
					br.close();
					return null;
				}
				dataset.attributes.add(att);
				
			} else if (strs[0].equalsIgnoreCase("@data")) {
				break;
			}
			line = br.readLine();
		}
		while (line != null) {
			line = br.readLine();
			int[] row = readArffDataRow(line,dataset);
			if(row != null)
				dataset.data.add(row);
		}
		br.close();
		return dataset;
	}
	private int[] readArffDataRow(String line,DataSet dataset) {
		if (line == null || line.trim().isEmpty())
			return null;
		String[] strs = line.split(",");
		int[] values = new int[dataset.getNumberOfAttributes()];
		for (int i = 0; i < strs.length; i++) {
			strs[i] = getNameFromString(strs[i]);
			if (strs[i].equals("?")|| dataset.getAttribute(i)== null)
				values[i] = -1;
			else
				values[i] = dataset.getAttribute(i).getNominalIndex(strs[i]);
		}
		return values;

	}
	private String[] getLineArffLabel(String line)
	{
		line = line.trim();
		if (line.length() > 0 && line.charAt(0) == '@') {
			return line.split(" ", 2);
		}
		return new String[]{""};
	}
	private Attribute readArffAttribute(String line) {
		String name;
		ArrayList<String> nominals = new ArrayList<String>();
		int openIndex = line.indexOf('{');
		int closeIndex = line.lastIndexOf('}');
		if (openIndex < 0 || openIndex > closeIndex)
		{
			return null;
		}
		name = getNameFromString(line.substring(0, openIndex));
		String nomLine = line.substring(openIndex + 1, closeIndex);
		String[] noms = nomLine.split(",");
		for (int i = 0; i < noms.length; i++) {
			nominals.add(getNameFromString(noms[i]));
		}
		return new Attribute(name, nominals);

	}
}
